#ifndef SINGLETON_H
#define SINGLETON_H

#include <memory>
#include <mutex>

template <typename T>
class Singleton
{
protected:
    Singleton() = default;
    ~Singleton() = default;

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static std::unique_ptr<T> m_instance;

public:
    static T& getInstance() {
        static std::once_flag s_flag;
        std::call_once(s_flag, [&](){
            m_instance = std::unique_ptr<T>(new T());
        });
        return *m_instance;
    }
};

template <typename T>
std::unique_ptr<T> Singleton<T>::m_instance = nullptr;

#endif